Particle in a Box#

What you need to know

Particle in a Box (PIB) as a Model System
The Particle in a Box (PIB) is a simple model that helps illustrate the behavior of electrons confined within atoms and molecules. It serves as a useful tool to introduce key quantum concepts:

  • Energetic Quantization: Energy levels in quantum systems are discrete, not continuous, as seen in the PIB model.

  • Probabilistic Nature of Quantum Particles: The probability distribution for the particle’s position is non-uniform, with nodal points where the probability is zero, emphasizing the inherent uncertainty in the particle’s exact location.

  • Uncertainty Principle: There is an inverse relationship between the uncertainty in position and momentum, demonstrating the fundamental limit on how precisely both quantities can be known simultaneously.

  • Zero-Point Energy: Quantum particles always possess a minimum kinetic energy, even at absolute zero. This zero-point energy highlights the impossibility of freezing all motion in quantum systems.

  • Quantum-Classical Correspondence: As the system scales up, quantum behavior smoothly transitions to classical behavior, illustrating the correspondence principle.

  • Degeneracy of Energy Levels: In systems with symmetries, multiple wave functions can correspond to the same energy level, a phenomenon known as degeneracy.

Classical vs Quantum particle in a box#

  • Particle in a box is a toy model of electron (or atom, molecule, small quantum object) trapped in some region of space \([0,L]\).

  • The positional information of a quantum “particle” is described by a quantum wave function \(\psi(x)\) which is obtained by solving Schrödinger equation with boundary conditions

  • Wave functions are standing waves just like in a guitar on a string problem. With one major difference! Quantum-wave function has a probabilistic meaning and hence has a completely different meaning from a classical notion of a “wave”.

  • According to classical mechanis in the absence of any attractive interactions particle will be boundicng back and forth between walls with constant speed. Hence and we expect to find particle with equal probability at all locations \(x\).

  • According to quantum mechancis Quantum particle in the box is going to be found in some regions with high probability in others with little or zero!

PIB-wiki

Fig. 51 The particle in a box (PIB) is a convenient system for illustrating the differences between classical (A) and quantum systems (B-F). The horizontal axis is position, and the vertical axis is the real part (blue) and imaginary part (red) of the wavefunction \(\psi_n(x)\). The states (B,C,D) are the eigenfunctions of Hamiltonian \(n=1,2,3\). While E and F are not.#

Solving the Schrödinger Equation for the Particle in a Box (PIB)#

Particle in a box

Fig. 52 Particle in a box subject to infinitely high potential walls#

The Schrödinger equation for a particle in a box (PIB) is defined by a Hamiltonian operator that incorporates the potential energy, which is infinitely large at the boundaries of the box and zero inside. This potential ensures that the particle is confined within the box, where it can only possess kinetic energy.

  • The potential energy for PIB is defined:

\[\begin{split} V(x) = \begin{cases} \infty & x = 0 \text{ or } x = L \\ 0 & 0 < x < L \end{cases} \end{split}\]
  • The boundary conditions are:

\[ \psi(0) = \psi(L) = 0 \]
  • The Hamiltonian operator is in this case accounting only for kinetic energy!

\[ \hat{H} = \hat{K} = -\frac{\hbar^2}{2m} \frac{d^2}{dx^2} \]
  • Now, we have all the necessary ingredients to solve the time-independent Schrödinger equation for the 1D PIB:

\[ \hat{H} \psi(x) = E \psi(x) \]
  • Substituting the Hamiltonian, we get:

\[ -\frac{\hbar^2}{2m} \frac{d^2}{dx^2} \psi(x) = E \psi(x) \]
\[ \psi''(x) = -k^2 \psi(x) \]
  • where the \(k^2\) is a positive real number that relates the particle’s energy \(E\) to its wavefunction.

\[ k^2 = \frac{2mE}{\hbar^2} \]

Solution and Boundary Conditions#

  • Mathematically, the form of the 1D PIB problem is similar to the ordinary differential equation (ODE) used in the 1D vibrating guitar string problem. The key differences lie in the constant coefficients and the interpretation of the wavefunction.

\[ \psi''(x) = -k^2 \psi(x) \]
  • The general solution to this differential equation is:

\[ \psi(x) = c_1 e^{ikx} + c_2 e^{-ikx} = A \cos(kx) + B \sin(kx) \]
  • Applying the boundary condition \(\psi(0) = 0\), we find that \(A = 0\), leaving us with:

\[ \psi(x) = B \sin(kx) \]
  • Applying the boundary condition \(\psi(L) = 0\), we get:

\[ B \sin(kL) = 0 \]
  • This condition is satisfied when:

\[ kL = n\pi \quad \text{or} \quad k = \frac{n\pi}{L} \]
  • Thus, the wavefunction becomes:

\[ \psi(x) = B \sin\left(\frac{n\pi}{L}x\right) \]
  • Using the relationship \(k^2 = \frac{n^2\pi^2}{L^2} = \frac{2mE}{\hbar^2}\), we can express the energy levels as:

\[ E_n = \frac{n^2 h^2}{8mL^2} \]
  • The quantization of energy results from confining the wavefunction within a finite space. This is the reason bound states exhibit quantized energy levels. Atoms, molecules, and solids all possess discrete energy levels due to similar constraints.

Wavefunctions Must Be Normalized#

  • Next, we determine the constant coefficient \(B_n\) by enforcing the normalization condition:

\[ \int_0^L \psi_n(x)^2 \, dx = 1\]
  • To evaluate the integral, we use the trigonometric identity \(\sin^2(x) = \frac{1}{2}(1 - \cos(2x))=1\)

\[ B_n^2 \int_0^L \sin^2\left(\frac{n\pi x}{L}\right) dx = \frac{B_n^2}{2} \int_0^L \left[ 1 - \cos\left(\frac{2n\pi x}{L}\right) \right] dx =1 \]
  • Since the integral of \(\cos\left(\frac{2n\pi x}{L}\right)\) over a full period from \(0\) to \(L\) is zero, we are left with:

\[ \frac{B_n^2}{2} \cdot L = 1 \]
  • Solving for \(B_n\) we determine normalization constant which ensures that square of wavefunction integrates to 1.

\[ B_n = \sqrt{\frac{2}{L}} \]

PIB Eigenfunctions and Eigenvalues#

Eigenfunctions and eigenvalues of 1D particle in a box

\[{\psi_n(x) = \Big (\frac{2}{L}\Big)^{\frac{1}{2}} \sin\frac{n\pi x}{L}}\]
\[{E_n=\frac{n^2 h^2}{8mL^2}}\]

Full time dependent solution

\[{\psi_n(x, t) = \Big (\frac{2}{L}\Big)^{\frac{1}{2}} \sin\frac{n\pi x}{L}}\cdot e^{-i\frac{E_n t}{\hbar}}\]
\[\Psi(x,t) = \sum_n c_n \psi_n(x, t)\]
  • Where the coefficients \(c_n\) depend on initial condition, e.g could be all zero except one (pure state) or a few of them non-zero (mixed state)

Hide code cell source
import numpy as np
import matplotlib.pyplot as plt

# Parameters
L = 1.0  # Length of the box
x = np.linspace(0, L, 1000)  # Position array
n_max = 5  # Maximum quantum number to display

# Constants
hbar = 1.0545718e-34  # Reduced Planck's constant (J·s)
m = 9.10938356e-31  # Mass of an electron (kg)

# Functions
def psi_n(n, x, L):
    """Wavefunction for a particle in a 1D box."""
    return np.sqrt(2 / L) * np.sin(n * np.pi * x / L)

def psi_n_squared(n, x, L):
    """Probability density (wavefunction squared)."""
    return psi_n(n, x, L) ** 2

def energy_levels(n, L):
    """Energy level for the particle in the box."""
    return (n**2 * np.pi**2 * hbar**2) / (2 * m * L**2)

# Energy formula string
energy_formula = r"$E_n = \frac{n^2 \pi^2 \hbar^2}{2mL^2}$"

# Plotting
fig, axs = plt.subplots(1, 2, figsize=(8, 6), sharey=True)

# Plot wavefunctions in the first subplot
for n in range(1, n_max + 1):
    wavefunction = psi_n(n, x, L)
    axs[0].plot(x, wavefunction + n**2, label=f'n={n}')
    axs[0].hlines(n**2, 0, L, colors='gray', linestyles='dashed')  # Energy level lines

# Wavefunction plot labels and title
axs[0].set_xlabel('Position (x)', fontsize=12)
axs[0].set_ylabel(r'$\psi_n(x)$', fontsize=12)
axs[0].legend(loc='upper right', bbox_to_anchor=(1.15, 1))

# Plot wavefunction squared (probability densities) in the second subplot
for n in range(1, n_max + 1):
    wavefunction_squared = psi_n_squared(n, x, L)
    axs[1].plot(x, wavefunction_squared + n**2, label=f'n={n}')
    axs[1].hlines(n**2, 0, L, colors='gray', linestyles='dashed')  # Energy level lines

# Probability density plot labels
axs[1].set_xlabel('Position (x)', fontsize=12)
axs[1].set_ylabel(r'$|\psi_n(x)|^2$', fontsize=12)

# Display the energy formula and levels in the second subplot
for n in range(1, n_max + 1):
    energy_value = energy_levels(n, L)
    axs[1].text(L, n**2, f"$E_{n}$ = {energy_value:.2e} J", verticalalignment='bottom', fontsize=12)

# Overall title for the figure
fig.suptitle(f'Wavefunctions and Energies for a 1D Particle in a Box (n=1 to n={n_max})')

# Make room for labels outside plot and improve layout
plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.show()
../_images/1f95b31bd9e839d2183b1c56587006bcb76e8b4256d279b234bf2ad88d1e2063.png

Discrete energy levels and zero point energy#

Quantum particles are never at rest

  • The lowest energy electon in a box can have is at \(n=1\) at which is not zero!

\[E_1 = h^2/8mL^2\]
  • Keeping in mind that the energy is purely kinetic, this means quantum particles never ceases their motion.

  • The spacing of energy levels is finite and depends on the size of the box!

\[E_{n+1} - E_n = (2n+1)\frac{h^2}{8mL^2}\]

Increasing Box size leads to more classical behavior

  • As the box size is increased energy spacing gets smaller!

  • Thus quantum effects are more pronounced when electorn is bound in smaller regions of space.

Non-uniform probabilities and nodes#

  • There are \(n-1\) nodes for quantum state \(n\)

  • Recall that sine function hitz zero at integer values of \(\pi\), \(sin(n\pi)=0\) when \(n=1,2,3,4,...\)

  • The wavefunction \(\psi_n(x) = sin \frac{n\pi x}{L}\) will then have \(n-1\) nodes at points \(x=L/n\), \(2L/n\), \(3L/n\), … \((n-1)L/n\).

  • Note that we do not count \(x=0\) and \(x=L\) points as nodes because they are part of boudnary conditions that apply to all wavefunctions

    • For instance \(n=3\) nodes are at \(x=L/3\), \(x=2L/3\).

    • For instance \(n=4\) nodes are at \(L/4\), \(2L/4\), \(3L/4\)

  • Nodes imply zero probability to find an electron in the box.

    • \(|\psi_n|^2=0\) at nodal points which means zero probability.

    • This is in sharp contradiction of classical mechanics which bases its prediction on purely particle like motion of electron.

    • Existence of nodes implies a wave like character of electron

On time-dependence#

Pure states#

  • Pure states correspond to time-independent probability distribution.

\[|\psi_n(x,t)|^2 = \psi_n(x,t)^{*}\cdot\psi_n(x,t) = \psi(x)e^{-iE_nt/\hbar}\cdot \psi(x)e^{+E_nt/\hbar} = |\psi(x)|^2\]
  • Below we visualize a few of the wavefunction at its square for \(n=2\).

Hide code cell source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

# Parameters
L = 1.0  # Length of the box
hbar = 1.0  # Set hbar = 1 for simplicity
m = 1.0  # Set mass = 1 for simplicity

# Define spatial and time arrays
x = np.linspace(0, L,  200)  
t = np.linspace(0, 10, 200)  

n = 2

# Define energy for nth state
def energy_n(n, L):
    return (n**2 * np.pi**2 * hbar**2) / (2 * m * L**2)

# Define wavefunction for nth state
def psi_total(n, x, L, t):
    E_n = energy_n(n, L)
    return np.sqrt(2 / L) * np.sin(n * np.pi * x / L) * np.exp(-1j * E_n * t / hbar)


# Set up the figure and axis
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 8))

# Set limits for the wavefunction and wavefunction squared
ax1.set_xlim(0, L)
ax1.set_ylim(-2, 2)
ax2.set_xlim(0, L)
ax2.set_ylim(0, 4)

# Set labels for the wavefunction plot
ax1.set_xlabel('Position (x)', fontsize=14)
ax1.set_ylabel(r'Re[$\psi(x,t)$]', fontsize=14)
ax1.set_title('Time Evolution of Wavefunction', fontsize=16)

# Set labels for the squared wavefunction plot
ax2.set_xlabel('Position (x)', fontsize=14)
ax2.set_ylabel(r'$|\psi(x,t)|^2$', fontsize=14)
ax2.set_title('Probability Density', fontsize=16)

### Animation settings 

# Initialize the wavefunction and its square plots
line_real, = ax1.plot([], [], lw=2)
line_prob, = ax2.plot([], [], lw=2)

# Initialization function for the plot
def init():
    line_real.set_data([], [])
    line_prob.set_data([], [])
    return line_real, line_prob

# Animation function which updates the plot each frame
def animate(i):
    t_val = t[i]
    psi = psi_total(n, x, L, t_val)
    psi_real = np.real(psi)
    psi_squared = np.abs(psi)**2
    line_real.set_data(x, psi_real)
    line_prob.set_data(x, psi_squared)
    return line_real, line_prob

# Create the animation
ani = FuncAnimation(fig, animate, init_func=init, frames=len(t), interval=150, blit=True)

plt.close(fig)  # Prevents static display of the last frame
HTML(ani.to_jshtml())
---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
Cell In[2], line 72
     69 ani = FuncAnimation(fig, animate, init_func=init, frames=len(t), interval=150, blit=True)
     71 plt.close(fig)  # Prevents static display of the last frame
---> 72 HTML(ani.to_jshtml())

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/animation.py:1352, in Animation.to_jshtml(self, fps, embed_frames, default_mode)
   1348         path = Path(tmpdir, "temp.html")
   1349         writer = HTMLWriter(fps=fps,
   1350                             embed_frames=embed_frames,
   1351                             default_mode=default_mode)
-> 1352         self.save(str(path), writer=writer)
   1353         self._html_representation = path.read_text()
   1355 return self._html_representation

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/animation.py:1107, in Animation.save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs, progress_callback)
   1105         progress_callback(frame_number, total_frames)
   1106         frame_number += 1
-> 1107 writer.grab_frame(**savefig_kwargs)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/animation.py:767, in HTMLWriter.grab_frame(self, **savefig_kwargs)
    765     return
    766 f = BytesIO()
--> 767 self.fig.savefig(f, format=self.frame_format,
    768                  dpi=self.dpi, **savefig_kwargs)
    769 imgdata64 = base64.encodebytes(f.getvalue()).decode('ascii')
    770 self._total_bytes += len(imgdata64)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/figure.py:3378, in Figure.savefig(self, fname, transparent, **kwargs)
   3374     for ax in self.axes:
   3375         stack.enter_context(
   3376             ax.patch._cm_set(facecolor='none', edgecolor='none'))
-> 3378 self.canvas.print_figure(fname, **kwargs)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/backend_bases.py:2366, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2362 try:
   2363     # _get_renderer may change the figure dpi (as vector formats
   2364     # force the figure dpi to 72), so we need to set it again here.
   2365     with cbook._setattr_cm(self.figure, dpi=dpi):
-> 2366         result = print_method(
   2367             filename,
   2368             facecolor=facecolor,
   2369             edgecolor=edgecolor,
   2370             orientation=orientation,
   2371             bbox_inches_restore=_bbox_inches_restore,
   2372             **kwargs)
   2373 finally:
   2374     if bbox_inches and restore_bbox:

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/backend_bases.py:2232, in FigureCanvasBase._switch_canvas_and_return_print_method.<locals>.<lambda>(*args, **kwargs)
   2228     optional_kws = {  # Passed by print_figure for other renderers.
   2229         "dpi", "facecolor", "edgecolor", "orientation",
   2230         "bbox_inches_restore"}
   2231     skip = optional_kws - {*inspect.signature(meth).parameters}
-> 2232     print_method = functools.wraps(meth)(lambda *args, **kwargs: meth(
   2233         *args, **{k: v for k, v in kwargs.items() if k not in skip}))
   2234 else:  # Let third-parties do as they see fit.
   2235     print_method = meth

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py:509, in FigureCanvasAgg.print_png(self, filename_or_obj, metadata, pil_kwargs)
    462 def print_png(self, filename_or_obj, *, metadata=None, pil_kwargs=None):
    463     """
    464     Write the figure to a PNG file.
    465 
   (...)
    507         *metadata*, including the default 'Software' key.
    508     """
--> 509     self._print_pil(filename_or_obj, "png", pil_kwargs, metadata)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py:457, in FigureCanvasAgg._print_pil(self, filename_or_obj, fmt, pil_kwargs, metadata)
    452 def _print_pil(self, filename_or_obj, fmt, pil_kwargs, metadata=None):
    453     """
    454     Draw the canvas, then save it using `.image.imsave` (to which
    455     *pil_kwargs* and *metadata* are forwarded).
    456     """
--> 457     FigureCanvasAgg.draw(self)
    458     mpl.image.imsave(
    459         filename_or_obj, self.buffer_rgba(), format=fmt, origin="upper",
    460         dpi=self.figure.dpi, metadata=metadata, pil_kwargs=pil_kwargs)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py:400, in FigureCanvasAgg.draw(self)
    396 # Acquire a lock on the shared font cache.
    397 with RendererAgg.lock, \
    398      (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    399       else nullcontext()):
--> 400     self.figure.draw(self.renderer)
    401     # A GUI class may be need to update a window using this draw, so
    402     # don't forget to call the superclass.
    403     super().draw()

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/figure.py:3175, in Figure.draw(self, renderer)
   3172         # ValueError can occur when resizing a window.
   3174 self.patch.draw(renderer)
-> 3175 mimage._draw_list_compositing_images(
   3176     renderer, self, artists, self.suppressComposite)
   3178 for sfig in self.subfigs:
   3179     sfig.draw(renderer)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    129 if not_composite or not has_images:
    130     for a in artists:
--> 131         a.draw(renderer)
    132 else:
    133     # Composite any adjacent images together
    134     image_group = []

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/axes/_base.py:3028, in _AxesBase.draw(self, renderer)
   3025     for spine in self.spines.values():
   3026         artists.remove(spine)
-> 3028 self._update_title_position(renderer)
   3030 if not self.axison:
   3031     for _axis in self._axis_map.values():

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/axes/_base.py:2972, in _AxesBase._update_title_position(self, renderer)
   2970 top = max(top, bb.ymax)
   2971 if title.get_text():
-> 2972     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2973     if ax.yaxis.offsetText.get_text():
   2974         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/axis.py:1337, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1334     renderer = self.figure._get_renderer()
   1335 ticks_to_draw = self._update_ticks()
-> 1337 self._update_label_position(renderer)
   1339 # go back to just this axis's tick labels
   1340 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/axis.py:2623, in YAxis._update_label_position(self, renderer)
   2620 except KeyError:
   2621     # use Axes if spine doesn't exist
   2622     spinebbox = self.axes.bbox
-> 2623 bbox = mtransforms.Bbox.union(bboxes + [spinebbox])
   2624 left = bbox.x0
   2625 self.label.set_position(
   2626     (left - self.labelpad * self.figure.dpi / 72, y)
   2627 )

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/transforms.py:658, in BboxBase.union(bboxes)
    656 y0 = np.min([bbox.ymin for bbox in bboxes])
    657 y1 = np.max([bbox.ymax for bbox in bboxes])
--> 658 return Bbox([[x0, y0], [x1, y1]])

File /opt/hostedtoolcache/Python/3.8.18/x64/lib/python3.8/site-packages/matplotlib/transforms.py:767, in Bbox.__init__(self, points, **kwargs)
    764     raise ValueError('Bbox points must be of the form '
    765                      '"[[x0, y0], [x1, y1]]".')
    766 self._points = points
--> 767 self._minpos = np.array([np.inf, np.inf])
    768 self._ignore = True
    769 # it is helpful in some contexts to know if the bbox is a
    770 # default or has been mutated; we store the orig points to
    771 # support the mutated methods

KeyboardInterrupt: 

Mixed states#

  • Mixed states show time dependence. Below we visualize lienar combination of the first two eigenfunctions of PIB.

\[ \psi(x,t) = c_1 \psi_1(x) e^{-iE_1t/\hbar} +c_2 \psi_2 e^{-iE_2t/\hbar} \]
Hide code cell source
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from IPython.display import HTML

# Parameters
L = 1.0  # Length of the box
hbar = 1.0  # Set hbar = 1 for simplicity
m = 1.0  # Set mass = 1 for simplicity

n_states = [1, 2]  # Quantum numbers for the superposition
coeffs = [1, 1]  # Coefficients for the superposition
coeffs = np.array(coeffs) / np.sqrt(np.sum(np.array(coeffs) ** 2))  # Normalize coefficients

# Define spatial and time arrays
x = np.linspace(0, L,  200)  
t = np.linspace(0, 10, 200)  

# Define wavefunction for nth state
def psi_n(n, x, L):
    return np.sqrt(2 / L) * np.sin(n * np.pi * x / L)

# Define energy for nth state
def energy_n(n, L):
    return (n**2 * np.pi**2 * hbar**2) / (2 * m * L**2)

# Define time-dependent wavefunction
def psi_total(x, t, L, coeffs, n_states):
    psi_t = np.zeros_like(x, dtype=complex)
    for idx, n in enumerate(n_states):
        psi_x = psi_n(n, x, L)
        E_n = energy_n(n, L)
        time_factor = np.exp(-1j * E_n * t / hbar)
        psi_t += coeffs[idx] * psi_x * time_factor
    return psi_t

# Set up the figure and axis
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(11, 8))

# Set limits for the wavefunction and wavefunction squared
ax1.set_xlim(0, L)
ax1.set_ylim(-2, 2)
ax2.set_xlim(0, L)
ax2.set_ylim(0, 4)

# Set labels for the wavefunction plot
ax1.set_xlabel('Position (x)', fontsize=14)
ax1.set_ylabel(r'Re[$\psi(x,t)$]', fontsize=14)
ax1.set_title('Time Evolution of Wavefunction', fontsize=16)

# Set labels for the squared wavefunction plot
ax2.set_xlabel('Position (x)', fontsize=14)
ax2.set_ylabel(r'$|\psi(x,t)|^2$', fontsize=14)
ax2.set_title('Probability Density', fontsize=16)

### Animation settings 

# Initialize the wavefunction and its square plots
line_real, = ax1.plot([], [], lw=2)
line_prob, = ax2.plot([], [], lw=2)

# Initialization function for the plot
def init():
    line_real.set_data([], [])
    line_prob.set_data([], [])
    return line_real, line_prob

# Animation function which updates the plot each frame
def animate(i):
    t_val = t[i]
    psi = psi_total(x, t_val, L, coeffs, n_states)
    psi_real = np.real(psi)
    psi_squared = np.abs(psi)**2
    line_real.set_data(x, psi_real)
    line_prob.set_data(x, psi_squared)
    return line_real, line_prob

# Create the animation
ani = FuncAnimation(fig, animate, init_func=init, frames=len(t), interval=150, blit=True)

plt.close(fig)  # Prevents static display of the last frame
HTML(ani.to_jshtml())

Quantum PIB in 3D#

pib1

Fig. 53 Particle in a 3D box subject to infinitely high potential walls.#

\[{-\frac{\hbar^2}{2m}\left(\frac{\partial^2\psi}{\partial x^2} + \frac{\partial^2\psi}{\partial y^2} + \frac{\partial^2\psi}{\partial z^2}\right) + V\psi = E\psi}\]
  • Where we set V=0 for particle inside the box and enforce the solutions \(\psi\) to be normalized wwithing the confines of the box (electron must be somewhere in the box!)

\[{\int\limits_{-\infty}^{\infty}\int\limits_{-\infty}^{\infty}\int\limits_{-\infty}^{\infty}\left|\psi(x,y,z)\right|^2dxdydz = 1}\]
  • Consider a particle in a box with sides of lengths \(a\) in \(x\), \(b\) in \(y\) and \(c\) in \(z\). The potential inside the box is zero and outside the box infinity. Again, the potential term can be treated by boundary conditions (i.e,. infinite potential implies that the wavefunction must be zero there). The above equation can be now written as:

\[\begin{split}{-\frac{\hbar^2}{2m}\Delta\psi = E\psi} \\ {\textnormal{with }\psi(a,y,z) = \psi(x,b,z) = \psi(x,y,c) = 0} \\ {\textnormal{and }\psi(0,y,z) = \psi(x,0,z) = \psi(x,y,0) = 0}\end{split}\]
  • Note the nabla symbol \(\Delta\) which concisely denotes the sum of three second order derivatives with respect to spatial variables. We will see this operators in all 3D problems.

  • In general, when the potential term can be expressed as a sum of terms that depend separately only on \(x, y\) and \(z\), the solutions can be written as a product:

\[{\psi(x,y,z) = X(x)Y(y)Z(z)}\]
  • By substituting and dividing by \(X(x)Y(y)Z(z)\), we obtain:

\[{-\frac{\hbar^2}{2m}\left[\frac{1}{X(x)}\frac{d^2X(x)}{dx^2} + \frac{1}{Y(y)}\frac{d^2Y(y)}{dy^2} + \frac{1}{Z(z)}\frac{d^2Z(z)}{dz^2}\right] = E}\]
  • The total energy \(E\) consists of a sum of three terms. Each tersm depends separately on \(x, y\) and \(z\). Thus we can write \(E = E_x + E_y + E_z\) and separate the equation into three one-dimensional problems.

\[\begin{split}{-\frac{\hbar^2}{2m}\left[\frac{1}{X(x)}\frac{d^2X(x)}{dx^2}\right] = E_x\textnormal{ with }X(0) = X(a) = 0}\\ {-\frac{\hbar^2}{2m}\left[\frac{1}{Y(y)}\frac{d^2Y(y)}{dy^2}\right] = E_y\textnormal{ with }Y(0) = Y(b) = 0}\\ {-\frac{\hbar^2}{2m}\left[\frac{1}{Z(z)}\frac{d^2Z(z)}{dz^2}\right] = E_z\textnormal{ with }Z(0) = Z(c) = 0}\end{split}\]
  • Thus we find that energy quantization due to spatial confinement of quantum wave function in X, Y and Z dimensions.

\[\begin{split}{X(x) = \sqrt{\frac{2}{a}}\sin\left(\frac{n_x\pi x}{a}\right)}\\ {Y(y) = \sqrt{\frac{2}{b}}\sin\left(\frac{n_y\pi y}{b}\right)}\\ {Z(z) = \sqrt{\frac{2}{c}}\sin\left(\frac{n_z\pi z}{c}\right)}\end{split}\]

Eigenfunctions and eigenvalues of particle in 3D Box#

  • Energy is quantized and when \(a = b = c\), we find that the energy levels can also be degenerate (i.e., the same energy with different values of \(n_x, n_y\) and \(n_z\)).

  • In most cases, degeneracy in quantum mechanics arises from symmetry. When \(a = b = c\), the lowest levels have the following degeneracy factors:

Problems#

Note on Computing Average Properties from a Wave Function

Because of the probabilistic interpretation of the wave function, average properties can be computed from the wave function. The general formula is

\[ \langle A \rangle = \int \psi^*(x)\hat{A}\psi(x)dx \]

where \(\hat{A}\) is any operator. This could be momentum, kinetic energy, etc. Below are a few problems illustrating how to do calculations

Problem 1: Compute probability of finding particle somehwere#

Compute the probability of observing the particle in a box being in the domain \(\frac{a}{3} \leq x \leq \frac{2a}{3}\).

Problem 2: Compute an expectation#

Compute he average of \(x^2\) for a particle in a box

Problem 3: Compute expectation of energy#

Compute the average Energy of Particle in a Box

Problem 4: Compute expectation of momentum#

Compute Average momentum for particle in a box

Problem 5#

Consider an electron in superfluid helium (\(^4\)He) where it forms a solvation cavity with a radius of \(18 \AA\). Calculate the zero-point energy and the energy difference between the ground and first excited states by approximating the electron by a particle in a 3-dimensional box.

Problem 6: Energy Levels in a 3D Box#

A particle is confined in a 3D box with side lengths \(L_x = L_y = L_z = L\). The energy levels for a particle in this box are given by the formula:

\[E_{n_x, n_y, n_z} = \frac{\hbar^2 \pi^2}{2mL^2} \left( n_x^2 + n_y^2 + n_z^2 \right)\]

where \(n_x\), \(n_y\), \(n_z\) are the quantum numbers associated with the particle’s motion in the \(x\)-, \(y\)-, and \(z\)-directions.

Calculate the energy levels for the quantum states with \(n_x = 1\), \(n_y = 1\), \(n_z = 2\) and \(n_x = 2\), \(n_y = 2\), \(n_z = 1\). Are these energy levels degenerate?

Problem 7: Degeneracy of Energy Levels#

Consider a particle confined in a cubic box with side lengths \(L_x = L_y = L_z = L\). The energy levels are given by the same formula as in Problem 1.

  • Part 1: Find the degeneracy of the energy level corresponding to the quantum number sum \(n_x^2 + n_y^2 + n_z^2 = 14\).

  • Part 2: Write down all the quantum number triplets \((n_x, n_y, n_z)\) that correspond to this energy level.

Problem 8: Degeneracy of the Ground State#

  • Part 1: What is the degeneracy of the ground state (the lowest energy state) for a particle in a cubic box?

  • Part 2: Explain why the ground state does not have degeneracy.

Problem 9: Higher Energy Degeneracy#

Consider a particle in a cubic box. The energy levels are quantized as:

\[E_{n_x, n_y, n_z} = \frac{\hbar^2 \pi^2}{2mL^2} \left( n_x^2 + n_y^2 + n_z^2 \right)\]
  • Part 1: Find the quantum numbers that give the same energy for the quantum number sum \(n_x^2 + n_y^2 + n_z^2 = 9\). How many degenerate states correspond to this energy?

  • Part 2: What is the degeneracy of this energy level?